/**
 * Project Reactor
 */


#ifndef _EVENTLOOP_H
#define _EVENTLOOP_H
#include "Acceptor.h"
#include "TcpConnection.h"
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <sys/eventfd.h>

using std::mutex;
using std::condition_variable;
using std::shared_ptr;
using std::vector;
using std::map;
using std::lock_guard;

class TcpConnection;

using TcpConnectionPtr = shared_ptr<TcpConnection>;

using TcpConnectionCallback = std::function<void(const TcpConnectionPtr &)>;

using Functor = std::function<void()>;

#define MAX_EVTLIST_SIZE 1024
//报错的原因是，别名写错了，然后报错写在了该文件的最后一行，宏定义上
//并写在了.cpp实现文件上，说是我的成员必须要是可修改的左值
class EventLoop {
private: 
    int m_epfd;
    vector<struct epoll_event> m_evtList;
    // struct epoll_event *m_evtList;
    Acceptor & m_acceptor;
    map<int,shared_ptr<TcpConnection>> m_connMap;
    bool m_isLooping;
    TcpConnectionCallback m_onNewConnection;
    TcpConnectionCallback m_onMessage;
    TcpConnectionCallback m_onClose;

    int m_evtfd;
    vector<Functor> m_pendings;
    mutex m_mutex;

public: 
    
/**
 * @param accept
 */
EventLoop(Acceptor & acceptor);
    
~EventLoop();
    
int createEpollFd();
    
/**
 * @param fd
 */
void addEpollReadFd(int fd);
    
/**
 * @param fd
 */
void delEpollReadFd(int fd);
    
void m_epoll_wait();
    
void handleNewConnection();
    
/**
 * @param fd
 */
void handleMessage(int fd);
    
void loop();
    
void unloop();
    
void waitEpollFd();

void setNewConnectionCallback(TcpConnectionCallback&& tcc);
    
/**
 * @param tcc
 */
void setMessageCallback(TcpConnectionCallback&& tcc);
    
/**
 * @param tcc
 */
void setCloseCallback(TcpConnectionCallback&& tcc);

int createEventFd();
    
void handleRead();
    
void wakeup();
    
void doPendingFunctors();
    
/**
 * @param cb
 */
void runInLoop(Functor && cb);

};

#endif //_EVENTLOOP_H